<template>
    <div>
        <div>
            <el-breadcrumb separator="/" style="margin: 8px;">
                <el-breadcrumb-item>预警结果数据</el-breadcrumb-item>
                <el-breadcrumb-item>团伙预警</el-breadcrumb-item>
            </el-breadcrumb>
        </div>
        <div class="container">
            <h3>团伙预警</h3>
            <div style="margin-top: 20px;">
                <el-form :inline="true" ref="query" :model="query">
                    <el-form-item label="创建时间" label-width="70px">
                        <el-date-picker v-model="date" class="common-input" type="datetimerange" range-separator="至"
                            start-placeholder="开始日期" end-placeholder="结束日期" @change="changeDate"
                            value-format="yyyy-MM-dd HH:mm:ss">
                        </el-date-picker>
                    </el-form-item>
                    <el-form-item label="事件名称" label-width="70px">
                        <el-input v-model="query.event_name" clearable class="common-width"
                            placeholder="请输入事件名称"></el-input>
                    </el-form-item>
                    <el-form-item label="事件类型" label-width="70px">
                        <el-input v-model="query.event_category" clearable class="common-width"
                            placeholder="请输入事件类型"></el-input>
                    </el-form-item>
                    <el-form-item label="源IP" label-width="70px">
                        <el-select v-model="query.source_ip" multiple filterable allow-create default-first-option
                            placeholder="请输入源IP">
                        </el-select>
                    </el-form-item>
                    <el-form-item label="目标IP" label-width="70px">
                        <el-select v-model="query.destination_ip" multiple filterable allow-create default-first-option
                            placeholder="请输入目标IP">
                        </el-select>
                    </el-form-item>
                    <el-form-item class="leftmargin">
                        <el-button type="primary" @click="getList">搜索</el-button>
                        <el-button type="primary" @click="getGraphList">团伙分析</el-button>
                        <el-button type="info" @click="resetSearch">重置</el-button>
                    </el-form-item>
                </el-form>
            </div>

            <el-tabs v-model="activeName" type="card" style="margin-top: 20px;" @tab-click="tabClick">
                <el-tab-pane label="日志查看" name="日志查看">
                    <el-table :data="tableData" class="table" align="center" ref="table">
                        <el-table-column prop="sourceIp" align="center" label="源ip"></el-table-column>
                        <el-table-column prop="destinationIp" align="center" label="目标ip"></el-table-column>
                        <el-table-column prop="startTime" align="center" label="创建时间"></el-table-column>
                        <el-table-column prop="eventName" align="center" label="事件名称"></el-table-column>
                        <el-table-column prop="eventCategory" align="center" label="事件类型"></el-table-column>
                        <el-table-column prop="detailPayload" align="center" label="攻击载荷"></el-table-column>
                        <el-table-column label="操作" align="center" width="120px">
                            <template slot-scope="scope">
                                <el-popconfirm title="确定要删除吗？" @confirm="deleteItem(scope.row.id)">
                                    <template #reference>
                                        <el-button type="text">删除</el-button>
                                    </template>
                                </el-popconfirm>
                            </template>
                        </el-table-column>
                    </el-table>
                    <div class="pagination">
                        <el-pagination background layout="total, prev, pager, next" :current-page="query.pageIndex"
                            :page-size="query.pageSize" :total="pageTotal"
                            @current-change="handlePageChange"></el-pagination>
                    </div>
                </el-tab-pane>
                <el-tab-pane label="团伙可视化" name="团伙可视化">
                    <div style="margin-bottom: 10px;text-align: right;">
                        <el-button size="small" @click="uploadAndDownload">导出</el-button>
                    </div>
                    <div style="height: 500px;width: 100%;" v-loading="loading" element-loading-text="加载中..."
                        element-loading-background="rgba(0, 0, 0, 0.3)">
                        <TuanHuoGraph :data="graphData" ref="graphDom" @getChildren="getChildren"
                            style="height: 100%;width: 100%;" />
                    </div>
                </el-tab-pane>
                <el-tab-pane label="团伙画像" name="团伙画像">

                </el-tab-pane>
            </el-tabs>

            <Huaxiang v-if="activeName == '团伙画像'" />

        </div>
    </div>
</template>
<script>
import TuanHuoGraph from '@/components/graph/TuanHuoGraph.vue'
import mockData from './mock.json'
import Huaxiang from './Huaxiang.vue'
const colors = [
    '#8FE9FF',
    '#87EAEF',
    '#FFC9E3',
    '#A7C2FF',
    '#FFA1E3',
    '#FFE269',
    '#BFCFEE',
    '#FFA0C5',
    '#D5FF86',
    '#7DA8FF',
    '#44E6C1',
    '#FF68A7',
    '#7F86FF',
    '#AE6CFF',
    '#FF5A34',
    '#5D7092',
    '#FF6565',
    '#6BFFDE',
    '#EAD9FF',
    '#CADBFF',
    '#A9FFEB',
    '#FFC4DD',
    '#CACDFF',
    '#FFD4F2',
    '#FFD3C9',
    '#EBF2FF',
    '#FFCBCB',
    '#CAFFF3',
    '#000033', '#000066', '#000099', '#0000cc', '#0000ff',
    '#003300', '#003333', '#003366', '#003399', '#0033cc', '#0033ff',
    '#006600', '#006633', '#006666', '#006699', '#0066cc', '#0066ff',
    '#009900', '#009933', '#009966', '#009999', '#0099cc', '#0099ff',
    '#00cc00', '#00cc33', '#00cc66', '#00cc99', '#00cccc', '#00ccff',
    '#00ff00', '#00ff33', '#00ff66', '#00ff99', '#00ffcc', '#00ffff',
    '#330000', '#330033', '#330066', '#330099', '#3300cc', '#3300ff',
    '#333300', '#333333', '#333366', '#333399', '#3333cc', '#3333ff',
    '#336600', '#336633', '#336666', '#336699', '#3366cc', '#3366ff',
    '#339900', '#339933', '#339966', '#339999', '#3399cc', '#3399ff',
    '#33cc00', '#33cc33', '#33cc66', '#33cc99', '#33cccc', '#33ccff',
    '#33ff00', '#33ff33', '#33ff66', '#33ff99', '#33ffcc', '#33ffff',
    '#660000', '#660033', '#660066', '#660099', '#6600cc', '#6600ff',
    '#663300', '#663333', '#663366', '#663399', '#6633cc', '#6633ff',
    '#666600', '#666633', '#666666', '#666699', '#6666cc', '#6666ff',
    '#669900', '#669933', '#669966', '#669999', '#6699cc', '#6699ff',
    '#66cc00', '#66cc33', '#66cc66', '#66cc99', '#66cccc', '#66ccff',
    '#66ff00', '#66ff33', '#66ff66', '#66ff99', '#66ffcc', '#66ffff',
    '#990000', '#990033', '#990066', '#990099', '#9900cc', '#9900ff',
    '#993300', '#993333', '#993366', '#993399', '#9933cc', '#9933ff',
    '#996600', '#996633', '#996666', '#996699', '#9966cc', '#9966ff',
    '#999900', '#999933', '#999966', '#999999', '#9999cc', '#9999ff',
    '#99cc00', '#99cc33', '#99cc66', '#99cc99', '#99cccc', '#99ccff',
    '#99ff00', '#99ff33', '#99ff66', '#99ff99', '#99ffcc', '#99ffff',
    '#cc0000', '#cc0033', '#cc0066', '#cc0099', '#cc00ff',
    '#cc3300', '#cc3333', '#cc3366', '#cc3399', '#cc33cc', '#cc33ff',
    '#cc6600', '#cc6633', '#cc6666', '#cc6699', '#cc66cc', '#cc66ff',
    '#cc9900', '#cc9933', '#cc9966', '#cc9999', '#cc99cc', '#cc99ff',
    '#cccc00', '#cccc33', '#cccc66', '#cccc99', '#cccccc', '#ccccff',
    '#ccffcc', '#ccffff', '#ccff00', '#ccff33', '#ccff66', '#ccff99',
    '#ccffcc', '#ccffff', '#ff0000', '#ff0033', '#ff0066', '#ff0099',
    '#ff00cc', '#ff00ff', '#ff3300', '#ff3333', '#ff3366', '#ff3399',
    '#ff33cc', '#ff33ff', '#ff6600', '#ff6633', '#ff6666', '#ff6699',
    '#ff66cc', '#ff66ff', '#ff9900', '#ff9933', '#ff9966', '#ff9999',
    '#ff99cc', '#ff99ff', '#ffcc00', '#ffcc33', '#ffcc66', '#ffcc99',
    '#ffcccc', '#ffccff'
];
export default {
    components: {
        TuanHuoGraph,
        Huaxiang,
    },
    data() {
        return {
            date: [],
            activeName: "日志查看",
            query: {
                source_ip: [],
                destination_ip: [],
                pageNum: 1,
                pageSize: 10,
            },
            tableData: [],
            pageTotal: 0,
            graphData: {},
            loading: false,
            exportData: [],
            requestId: "6",
            nodesSet: ["11", "12", "13", "14", "-1", "15", "16", "17", "18", "19", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "20", "10", "21"],
        };
    },
    created() {
        this.getList();
    },
    methods: {
        async getList() {
            const res = await this.$http.postJson("/api/findEventLogs", {
                ...this.query,
            })
            this.tableData = res.content
            this.pageTotal = res.totalElements
        },
        async deleteItem(id) {
            const res = await this.$http.fetchGet("/api/deleteOneEventLog", { id: id })
            this.$message.success("操作成功")
            this.getList()
        },
        // 分页导航
        handlePageChange(val) {
            this.$set(this.query, 'pageNum', val);
            this.getList();
        },
        changeDate(val) {
            if (!val) {
                delete this.query.start_time;
                delete this.query.end_time;
            } else {
                this.query.start_time = val[0];
                this.query.end_time = val[1];
            }
        },
        resetSearch() {
            let query = {
                pageNum: this.query.pageNum,
                pageSize: this.query.pageSize,
                source_ip: [],
                destination_ip: [],
            };
            this.query = query
            this.date = []
            this.getList()
        },
        tabClick() {
            if (this.activeName == '团伙可视化' && !this.graphData.nodes) {
                this.getGraphList()
            }
        },
        async getGraphList() {
            this.loading = true
            const res = await this.$http.postJson("/api/sendEventLogs", {
                ...this.query,
            })
            console.log("团伙可视化接口返回", res)
            this.requestId = res.id
            this.nodesSet = res.nodesSet
            this.initData(res.nodesSet)
            this.exportData = res.des
            this.loading = false
        },
        initData(nodesSet) {
            let nodes = []
            let edges = []
            for (const key in nodesSet) {
                const colorIndex = key % colors.length; // 根据 group_id 确定颜色
                nodes.push({
                    id: key,
                    label: `${key}\n（${nodesSet[key]}个）`,
                    info: {
                        Group_id: key,
                        isFirst: true,
                    },
                    size: '100',
                    style: {
                        fill: colors[key] || '#5B8FF9', //节点填充色
                        // stroke:  //节点的描边颜色
                        lineWidth: 0, //描边宽度
                    },
                    labelCfg: {
                        position: 'center',
                        style: {
                            fill: '#FFFFFF',
                            fontSize: 26,
                        }
                    },
                })
            }
            this.graphData = {
                nodes,
                edges
            }
            this.setGraphData()
            console.log("this.graphData", this.graphData)
        },
        async uploadAndDownload() {
            const jsonStr = JSON.stringify(this.exportData, null, 2);
            const blob = new Blob([jsonStr], { type: 'application/json' });
            const url = URL.createObjectURL(blob);
            const link = document.createElement('a');
            link.href = url;
            link.download = 'data.json';
            document.body.appendChild(link);
            link.click();
            document.body.removeChild(link);
            URL.revokeObjectURL(url);
            this.$sendLog({
                operateFuncName: "团伙预警",
                operateFuncKey: "Criminal Group Alert",
                operateInfo: "导出团伙分析",
                operateKey: "download",
            })
        },
        async getChildren(GroupId) {
            if (this.graphData.nodes.length > 50) {
                this.initData(this.nodesSet)
                return
            }
            const res = await this.$http.fetchGet("/api/listByGroupId", { groupId: GroupId, requestId: this.requestId })
            // const res = mockData
            const nodes = res.data.nodes.map(item => {
                const colorIndex = GroupId % colors.length; // 根据 group_id 确定颜色
                return {
                    id: item.Id,
                    label: item.Id,
                    info: item,
                    style: {
                        stroke: colors[colorIndex] || '#5B8FF9', //节点的描边颜色
                    },
                }
            })
            // console.log("res",res.data.edges)
            const edges = res.data.nodes.map(item => {
                return {
                    source: GroupId,
                    target: item.Id,
                }
            })
            this.mergeData({ nodes, edges })
        },
        // 合并数据
        mergeData({ edges, nodes }) {
            console.log("edges, nodes", edges, nodes)
            let graphData = this.$cloneDeep(this.graphData)
            console.log("this.graphData", graphData)
            this.graphData = { nodes: [...graphData.nodes, ...nodes], edges: edges }
            this.setGraphData()
        },
        setGraphData() {
            this.$refs.graphDom.handleResize()
            this.$refs.graphDom.setData(this.graphData)
        },
    }
};
</script>

<style scoped>
.common-width {
    width: 180px;
}

.common-select {
    width: 350px;
}

.common-input {
    width: 350px;
}

.small-input {
    width: 225px;
}

.table {
    width: 100%;
    font-size: 14px;
}

.green {
    color: #67c23a;
}

.blue {
    color: #409eff;
}

.origin {
    color: #ff7300;
}

.red {
    color: #f56c6c;
}

.leftmargin {
    margin-left: 10px;
}

.mr10 {
    margin-right: 10px;
}

.form>>>.el-form-item--mini.el-form-item,
.el-form-item--small.el-form-item {
    margin-bottom: 10px;
}
</style>